package io.rong.app.utils;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import com.yunshipei.db.DatabaseUtil;
import com.yunshipei.common.Globals;
import com.yunshipei.manager.YspPreferences;
import com.yunshipei.model.UserInfo;
import com.yunshipei.utils.BaseUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Formatter;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import io.rong.app.model.GroupCreateInfo;
import io.rong.app.model.SortModelHaveCheck;
import io.rong.imkit.RongContext;
import io.rong.message.TextMessage;

/**
 * Created by cike on 15-10-21.
 */
public class StringUtilSub {
    public static final int WAY_STATE0 = 0;
    public static final int WAY_STATE1 = 1;
    public static final int WAY_STATE2 = 2;
    public static final String TIME_FORMAT = "yyyy-MM-dd hh:mm:ss";
    private static StringUtilSub stringUtil;
    private static DatabaseUtil databaseUtil;

    private StringUtilSub() {
        databaseUtil = new DatabaseUtil();
    }

    public static StringUtilSub getInstance() {
        if (stringUtil == null)
            stringUtil = new StringUtilSub();
        return stringUtil;
    }

    public static boolean checkNull(String string) {
        boolean isNull = true;
        if (string != null && string.length() >= 0)
            isNull = false;
        return isNull;
    }

    /**
     * way == 0 时,从开头截取,
     * way == 1时,从尾截取
     *
     * @param way
     * @param oldStr       被截取字符串
     * @param sonStrLenght 子串长度
     * @return
     */
    public String subSting(int way, String oldStr, int sonStrLenght) {
        int strBufLength;
        if (!checkNull(oldStr)) {
            StringBuffer strBur = new StringBuffer(oldStr);
            strBufLength = strBur.length();
            if (way == WAY_STATE0) {
                if (sonStrLenght < strBufLength)
                    return strBur.substring(0, sonStrLenght - 1).toString();
                else if (sonStrLenght >= strBufLength)
                    return oldStr;


            } else if (way == WAY_STATE1) {
                if (sonStrLenght < strBufLength)
                    return strBur.substring(sonStrLenght - sonStrLenght - 1, sonStrLenght - 1).toString();
                else if (sonStrLenght >= strBufLength)
                    return oldStr;
            }
        }
        return null;
    }

    /**
     * 截取字符串添加（..）
     *
     * @param way
     * @param oldStr
     * @param sonStrLenght
     * @return
     */

    public static String SubStringAddCH(int way, String oldStr, int sonStrLenght) {
        int strBufLength;
        if (!checkNull(oldStr)) {
            StringBuffer strBur = new StringBuffer(oldStr);
            strBufLength = strBur.length();
            if (way == WAY_STATE0) {
                if (sonStrLenght < strBufLength)
                    return strBur.substring(0, sonStrLenght - 1).toString() + "..";
                else if (sonStrLenght >= strBufLength)
                    return oldStr;


            } else if (way == WAY_STATE1) {
                if (sonStrLenght < strBufLength)
                    return strBur.substring(sonStrLenght - sonStrLenght - 1, sonStrLenght - 1).toString() + "..";
                else if (sonStrLenght >= strBufLength)
                    return oldStr;
            } else if (way == WAY_STATE2) {
                if (sonStrLenght < strBufLength) {
                    int start = strBufLength - sonStrLenght;
                    return ".." + strBur.substring(start > 0 ? start : 0, strBufLength).toString();
                } else if (sonStrLenght >= strBufLength)
                    return oldStr;
            }
        }
        return null;
    }

    /**
     * 删除空格
     *
     * @param str
     * @return
     */
    public static String replaceBlank(String str) {
        return BaseUtil.replaceBlank(str);
    }

    /**
     * 判断字符串是否相等
     *
     * @param str1
     * @param str2
     * @return
     */
    public static boolean judgeSame(String str1, String str2) {
        boolean state = false;
        if (!checkNull(str1)) {
            if (str1.equals(str2)) {
                state = true;
            }
        }
        return state;
    }

    public String notificationContextCheck(String userName, String pushMessage) {
        if (userName != null) {
            int userNameLength = userName.length();
            if (!checkNull(pushMessage)) {
                String pushMessageSub = subSting(0, replaceBlank(pushMessage), userNameLength + 1);
                if (judgeSame(userName, pushMessageSub)) {
                    return pushMessage.substring(userNameLength + 1, pushMessage.length());
                }
            } else {
                Log.e("StringUtilSub", "pushMessage is null");
            }
            return pushMessage;
        }
        return "";
    }

    // 根据Unicode编码完美的判断中文汉字和符号
    private static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
            return true;
        }
        return false;
    }

    // 完整的判断中文汉字和符号
    public static boolean isChinese(String strName) {
        char[] ch = strName.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if (isChinese(c)) {
                return true;
            }
        }
        return false;
    }

    // 只能判断部分CJK字符（CJK统一汉字）
    public static boolean isChineseByREG(String str) {
        if (str == null) {
            return false;
        }
        Pattern pattern = Pattern.compile("[\\u4E00-\\u9FBF]+");
        return pattern.matcher(str.trim()).find();
    }

    public static GroupCreateInfo SqlToObj(JSONObject result) {
        GroupCreateInfo group = new GroupCreateInfo();
        group.setId(result.optString("id"));
        group.setName(result.optString("name"));
        group.setIntroduce(result.optString("introduce"));
        group.setNumber(result.optInt("number"));
        group.setMax_number(result.optInt("max_number"));
        group.setCreate_user_id(result.optString("create_user_id"));
        group.setCreate_dateTime(result.optString("create_dateTime"));
        if (result.isNull("avatar")) {
            group.setPortraitUri("");
        } else {
            group.setPortraitUri(result.optString("avatar"));
        }
        JSONArray array = result.optJSONArray("groupMembers");
        group.setGourpMembers(array == null ? "" : array.toString());
        return group;
    }

    // 使用系统当前日期加以调整作为照片的名称
    public static String getPhotoFileName() {
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat dateFormat = new SimpleDateFormat("'IMG'_yyyyMMdd_HHmmss");
        return dateFormat.format(date) + ".jpg";
    }

    /**
     * 获取metadata
     *
     * @param packageName
     * @param metaTarget
     * @return
     */
    public static String getApplicationMeteData(Context context, String packageName, String metaTarget) {
        ApplicationInfo appInfo = null;
        String msg = "";
        try {
            appInfo = context.getPackageManager()
                    .getApplicationInfo(packageName,
                            PackageManager.GET_META_DATA);
            msg = appInfo.metaData.getString(metaTarget);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return msg;
    }

    /**
     * 获取融云conversationList info(会话列表数据持久化目录)
     *
     * @param context
     * @return
     */
    public static String getRongCloudDatabasePath(Context context) {
        String uuid = YspPreferences.getInstance().getSharedPreferences().getString(Globals.UUID, "");
        String path = Environment.getDataDirectory().getAbsolutePath() + "/data/" + context.getPackageName() +
                "/files/" + getApplicationMeteData(context, context.getPackageName(), "RONG_CLOUD_APP_KEY")
                + "/" + uuid +
                "/storage";
        return path;
    }

    /**
     * 截取字符串
     *
     * @param originalStr
     * @return
     */
    public static String getEndword(String originalStr) {
        String endWord;
        if (originalStr != null) {
            int len = originalStr.length();
            if (len >= 1) {
                endWord = originalStr.substring(len - 1, len);
            } else {
                endWord = originalStr;
            }
            return endWord;
        } else {
            return "";
        }
    }

    public static String removeOldMemberUuid(String mApiResult, String str) {
        try {
            JSONArray json = new JSONArray(mApiResult);
            JSONArray newJson = new JSONArray();
            for (int i = 0; i < json.length(); i++) {
                if (!json.get(i).equals(str)) {
                    newJson.put(json.get(i));
                }
            }
            return newJson.toString();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解析群组成员
     *
     * @param userList
     * @return
     */
    public static String splitString(List<SortModelHaveCheck> userList) {
        StringBuffer stringBuffer = new StringBuffer();
        int size = userList.size();
        for (int i = 0; size >= 1 && i < size - 1; i++) {
            stringBuffer.append(userList.get(i).getSortModel().getUserInfo().getUuid() + ",");
        }
        if (size > 0)
            stringBuffer.append(userList.get(size - 1).getSortModel().getUserInfo().getUuid());
        return stringBuffer.toString();
    }

    /**
     * 判断群组成员是否已经存在
     *
     * @param str
     * @param uuids
     * @return
     */
    public static boolean judgeExist(String str, String uuids) {
        boolean bool = false;
        try {
            JSONArray jsonArray = new JSONArray(uuids);
            for (int j = 0; j < jsonArray.length(); j++) {
                if (str.equals(jsonArray.get(j))) {
                    bool = true;
                    // break;

                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return bool;
    }

    /**
     * 群组成员添加
     *
     * @param mApiResult
     * @param str
     * @return
     */
    public static String addNewMemberUuid(String mApiResult, String str) {
        if (checkContain(mApiResult, str)) {
            return mApiResult;
        } else {
            String result;
            str = '"' + str;
            str = str + '"';
            StringBuffer strBuffer = new StringBuffer(mApiResult);
            int size = strBuffer.length();
            String newStrBuffer = strBuffer.substring(0, size - 1);
            strBuffer = new StringBuffer(newStrBuffer);
            newStrBuffer = strBuffer.append(',').toString();
            newStrBuffer = newStrBuffer + str + "]";
            return newStrBuffer;
        }
    }

    /**
     * 检查是否addStr
     *
     * @param membersArray
     * @param addStr
     * @return
     */
    private static boolean checkContain(String membersArray, String addStr) {
        try {
            JSONArray jsonArray = new JSONArray(membersArray);
            for (int i = 0; i < jsonArray.length(); i++) {
                if (jsonArray.get(i).equals(addStr))
                    return true;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 检测电话链接格式
     *
     * @pa @return
     */
    public static boolean isTelPhoneLink(String str) {
        Pattern pattern = Pattern.compile("tel:[0-9]*");
        Matcher isnum = pattern.matcher(str);
        if (!isnum.matches()) {
            return false;
        }
        return true;
    }

    /**
     * 检测邮箱
     *
     * @param str
     * @return
     */
    public static boolean isEmailLink(String str) {
        Pattern pattern = Pattern.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");
        Matcher ismail = pattern.matcher(str);
        return ismail.matches();
    }

    public static boolean isPassword(String str) {
        Pattern pattern = Pattern.compile("^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]{6,16}$");
        Matcher isPass = pattern.matcher(str);
        return isPass.matches();
    }

    //群名称格式匹配
    public static boolean nameFormat(String name) {
        if (TextUtils.isEmpty(name))
            return false;
        Pattern pattern = Pattern.compile("^[0-9a-zA-Z]+$");
        Matcher isPass = pattern.matcher(name);
        return isPass.matches();
    }

    /**
     * 匹配网址
     *
     * @param string
     * @return
     */
    public static boolean isNetWorkAddr(String string) {
        Pattern pattern = Pattern.compile("(http://|ftp://|https://|www){0,1}[^\u4e00-\u9fa5\\s]*?\\.(com|net|cn|me|tw|fr)[^\u4e00-\u9fa5\\s]*");
        Matcher isNetWorkAddr = pattern.matcher(string);
        return isNetWorkAddr.matches();
    }

    public static Matcher isAt(String string) {
        Pattern pattern = Pattern.compile("\\@\\w+\\s");
        Matcher matcher = pattern.matcher(string);
        return matcher;
    }

    public static TextMessage replaceUuid(String content) {
        Matcher matcher = isAt(content);
        JSONArray uuids = new JSONArray();
        JSONObject atJson = new JSONObject();
        try {
            while (matcher.find()) {
                String uuidStr = matcher.group();
                if (!TextUtils.isEmpty(uuidStr)) {
                    String uuid = uuidStr.substring(1, uuidStr.length() - 1);
                    System.out.println("uuid = " + uuid);
                    UserInfo userInfo = databaseUtil.queryUserInfoByid(uuid);
                    content = content.replaceAll(uuid, userInfo != null ? userInfo.getName() : "");
                    uuids.put(uuid);
                }
            }
            atJson.put("at", uuids);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        TextMessage textMessage = TextMessage.obtain(content);
        textMessage.setExtra(atJson.toString());
        Log.d("replaceUuid", content);
        return textMessage;
    }

    public static boolean checkExtra(String string) {
        try {
            if (!TextUtils.isEmpty(string)) {
                JSONObject extra = null;
                extra = new JSONObject(string);
                JSONArray uuids = extra.getJSONArray("at");
                for (int i = 0; i < uuids.length(); i++) {
                    io.rong.imlib.model.UserInfo userInfo = RongContext.getInstance().getCurrentUserInfo();
                    if (uuids.getString(i).equals(userInfo.getUserId())) {
                        return true;
                    }
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    public static String base64(Object obj) {
        if (obj != null) {
            String base64 = null;
            try {
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
                objectOutputStream.writeObject(obj);
                base64 = new String(org.apache.commons.codec.binary.Base64.encodeBase64(byteArrayOutputStream.toByteArray()));
                byteArrayOutputStream.close();
                objectOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return base64;
        }
        return null;
    }

    public static Object getEncodeBase64(String base64) {
        if (!TextUtils.isEmpty(base64)) {
            Object obj = null;
            try {
                byte[] pb = org.apache.commons.codec.binary.Base64.decodeBase64(base64.getBytes());
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(pb);
                ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
                obj = objectInputStream.readObject();
                byteArrayInputStream.close();
                objectInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return obj;
        }
        return null;
    }

    /**
     * 用于聊天消息记录匹配
     *
     * @param matcheredStr
     * @param matcherStr
     * @return
     */
    public static String matcher(String matcheredStr, String matcherStr) {
        List<String> list = new ArrayList<>();
        Pattern pattern = Pattern.compile("*" + matcherStr + "*");
        Matcher matcher = pattern.matcher(matcheredStr);
        while (matcher.find()) {
            String str = matcher.group();
            if (!TextUtils.isEmpty(str)) {
                list.add(str);
            }
        }
        return null;
    }

    public static String hmacSha1(String base, String key) throws NoSuchAlgorithmException, InvalidKeyException {

        String type = "HmacSHA1";

        SecretKeySpec secret = new SecretKeySpec(key.getBytes(), type);

        Mac mac = Mac.getInstance(type);

        mac.init(secret);

        byte[] digest = mac.doFinal(base.getBytes());

        return Base64.encodeToString(digest, Base64.DEFAULT);
    }

    private static String toHexString(byte[] bytes) {
        Formatter formatter = new Formatter();

        for (byte b : bytes) {
            formatter.format("%02x", b);
        }

        return formatter.toString();
    }

    public static String calculateRFC2104HMAC(String data, String key)
            throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
        SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(signingKey);
        return toHexString(mac.doFinal(data.getBytes()));
    }

    /**
     * url 拼接 处理File.separator
     *
     * @param host
     * @param path
     * @return
     */
    public static String dealSeparator(String host, String path) {
        int length = host.length();
        if (!TextUtils.isEmpty(host) && !TextUtils.isEmpty(path)) {
            if ((host.charAt(length - 1) == '/' && path.charAt(0) != '/')
                    || (host.charAt(length - 1) != '/' && path.charAt(0) == '/')) {
                return host + path;
            } else if (host.charAt(length - 1) == '/' && path.charAt(0) == '/') {
                return host + path.substring(1, path.length());
            } else if (host.charAt(length - 1) != '/' && path.charAt(0) != '/') {
                return host + File.separator + path;
            }
        }
        return null;
    }

}